//
//  TypeCastingExample.swift
//  SwiftCode
//
//  Created by yuhus on 2023/12/26.
//

import Foundation

class TypeCastingExample: ListViewController {
  override func getItemCount() -> Int {
    data.count
  }
  
  override func getItem(_ indexPath: IndexPath) -> Item {
    data[indexPath.row]
  }
  
  private lazy var data: [Item] = [
    .init(title: "Any & AnyObject", description: "Any 和 AnyObject 的类型转换", action: anyTypeCasting),
  ]
}

class MediaItem {
  var name: String
  init(name: String) {
    self.name = name
  }
}

class Movie: MediaItem {
  var director: String
  init(name: String, director: String) {
    self.director = director
    super.init(name: name)
  }
}

class Song: MediaItem {
  var artist: String
  init(name: String, artist: String) {
    self.artist = artist
    super.init(name: name)
  }
}

private func anyTypeCasting() {
  var things: [Any] = []
  
  things.append(0)
  things.append(0.0) // Double
  things.append(42)
  things.append(3.14159) // Double
  things.append("hello")
  things.append((3.0, 5.0)) // 元组 (Double, Double)
  things.append(Movie(name: "Ghostbusters", director: "Ivan Reitman"))
  things.append({ (name: String) -> String in "Hello, \(name)" }) // 闭包表达式
  
  for thing in things {
    switch thing {
    case 0 as Int:
      print("zero as an Int")
    case 0 as Double:
      print("zero as a Double")
    case let someInt as Int:
      print("an integer value of \(someInt)")
    case let someDouble as Double where someDouble > 0:
      print("a positive double value of \(someDouble)")
    case is Double:
      print("some other double value that I don't want to print")
    case let someString as String:
      print("a string value of \"\(someString)\"")
    case let (x, y) as (Double, Double):
      print("an (x, y) point at \(x), \(y)")
    case let movie as Movie:
      print("a movie called \(movie.name), dir. \(movie.director)")
    case let stringConverter as (String) -> String:
      print(stringConverter("Michael"))
    default:
      print("something else")
    }
  }
  
  // zero as an Int
  // zero as a Double
  // an integer value of 42
  // a positive double value of 3.14159
  // a string value of "hello"
  // an (x, y) point at 3.0, 5.0
  // a movie called Ghostbusters, dir. Ivan Reitman
  // Hello, Michael
}
